"""doc"""

import json

from pprint import pprint


from django.test import TestCase


from django.test import RequestFactory, TestCase, Client
from django.utils import timezone

from django.contrib.auth import (
    get_user_model,
)

from rest_framework import status

from . import models


class CommunityTest(TestCase):
    """doc"""

    _models = models.Community

    @classmethod
    def creat_community(cls):
        """doc"""
        _list = [
            {
                "community_name": "小区a",
                "property_unit_price": 1,
                "display_url": "https://xxx",
            },
            {
                "community_name": "小区a",
                "property_unit_price": 1,
                "display_url": "https://xxx",
            },
        ]
        _bulk = (cls._models(**v) for v in _list)
        return cls._models.objects.bulk_create(_bulk)

    def setUp(self):
        # Every test needs access to the request factory.
        self.c = Client()
        self.factory = RequestFactory()
        self.admin_user = {"username": "admin", "password": "admin123"}

        self.creat_community()

        # init status
        self.create_admin()
        self.admin_login()

    def create_admin(self):
        # doc
        User = get_user_model()
        User.objects.create_superuser(email="myemail@test.com", **self.admin_user)

    def admin_login(self):
        resp = self.c.post(
            "/api/admin/login",
            data=self.admin_user,
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)

    # python manage.py test app_community.tests.CommunityTest
    def test_get_community(self):
        """doc"""

        # get community
        resp = self.c.get(
            "/api/community/",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)

        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(len(_data), 2)


# Create your tests here.
class HouseTest(TestCase):
    _models = models.House
    _url = "/api/community/house"

    @classmethod
    def create_house(cls):
        cls.comm_s = CommunityTest.creat_community()
        _list = [
            {
                "community_uuid": cls.comm_s[0].uuid,
                "building_num": "8",
                "unit_num": "6",
                "house_num": "2203",
                "area_size": 99,
                "paid_at": "2023-04-08",
            },
            {
                "community_uuid": cls.comm_s[0].uuid,
                "building_num": "7",
                "unit_num": "6",
                "house_num": "2203",
                "area_size": 99,
                "paid_at": "2023-04-08",
            },
        ]
        _bulk = (cls._models(**v) for v in _list)
        return {"comm_s": cls.comm_s, "house_s": cls._models.objects.bulk_create(_bulk)}

    def setUp(self):
        # Every test needs access to the request factory.
        self.c = Client()
        self.factory = RequestFactory()
        self.admin_user = {"username": "admin", "password": "admin123"}

        self.house_s = self.create_house()["house_s"]
        # init status
        self.create_admin()
        self.admin_login()

    def create_admin(self):
        # doc
        User = get_user_model()
        User.objects.create_superuser(email="myemail@test.com", **self.admin_user)

    def admin_login(self):
        resp = self.c.post(
            "/api/admin/login",
            data=self.admin_user,
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)

    # python manage.py test app_community.tests.HouseTest
    def test_get_house(self):
        # doc
        resp = self.c.get(
            f"{self._url}?community_uuid={self.comm_s[0].uuid}",
        )
        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(len(_data), 2)

    # python manage.py test app_community.tests.HouseTest.test_post_house
    def test_post_house(self):
        # doc
        _list = [
            {
                "community_uuid": self.comm_s[0].uuid,
                "building_num": "13",
                "unit_num": "6",
                "house_num": "2203",
                "area_size": 99,
            },
            {
                "community_uuid": self.comm_s[0].uuid,
                "building_num": "12",
                "unit_num": "6",
                "house_num": "2203",
                "area_size": 99,
            },
        ]
        resp = self.c.post(
            self._url,
            data={"list": _list},
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(len(_data), 2)


class HouseBillTest(TestCase):
    _models = models.HouseBill
    _url = "/api/community/house_bill"

    @classmethod
    def create_house_bill(cls):
        res = HouseTest.create_house()
        cls.comm_s = res["comm_s"]
        cls.house_s = res["house_s"]

        cls._list = [
            {
                "house_uuid": cls.house_s[0].uuid,
                "days": "31",
                "start_at": timezone.now(),
                "pay_user_openid": "0" * 32,
            },
            {
                "house_uuid": cls.house_s[0].uuid,
                "days": "7",
                "start_at": timezone.now(),
                "pay_user_openid": "0" * 32,
            },
        ]
        _bulk = list(cls._models(**v) for v in cls._list)
        res["house_bill_s"] = models.batch_create_house_bill(_bulk)
        return res

    def setUp(self):
        # Every test needs access to the request factory.
        self.c = Client()
        self.factory = RequestFactory()
        self.admin_user = {"username": "admin", "password": "admin123"}

        self.house_bill_s = self.create_house_bill()["house_bill_s"]
        # init status
        self.create_admin()
        self.admin_login()

    def create_admin(self):
        # doc
        User = get_user_model()
        User.objects.create_superuser(email="myemail@test.com", **self.admin_user)

    def admin_login(self):
        resp = self.c.post(
            "/api/admin/login",
            data=self.admin_user,
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)

    # python manage.py test app_community.tests.HouseBillTest.test_get_house_bill
    def test_get_house_bill(self):
        # doc
        resp = self.c.get(
            f"{self._url}?house_uuid={self.house_s[0].uuid}",
        )
        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(len(_data), 2)

    # python manage.py test app_community.tests.HouseBillTest.test_post_house_bill
    def test_post_house_bill(self):
        # doc
        resp = self.c.post(
            self._url,
            data={"list": self._list * 2},
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(len(_data), 4)

    # python manage.py test app_community.tests.HouseBillTest.test_del_house_bill
    def test_del_house_bill(self):
        # doc
        resp = self.c.post(
            self._url,
            data={"list": self._list * 2},
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(len(_data), 4)

        # del house bill
        resp = self.c.delete(
            self._url,
            data={"list": [x["uuid"] for x in _data]},
            content_type="application/json",
        )
        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        _content = json.loads(resp.content)
        _data = _content["data"]
        self.assertEqual(_data, "del count: 4")

    # python manage.py test app_community.tests.HouseBillTest.test_bill_state
    def test_bill_state(self):
        pprint({"data": models.HouseBill.BillState.values})
